home *** CD-ROM | disk | FTP | other *** search
/ Collection of Tools & Utilities / Collection of Tools and Utilities.iso / asmutil / afloat.zip / F_ADD.ASM < prev    next >
Assembly Source File  |  1988-03-14  |  4KB  |  178 lines

  1.         PAGE ,132
  2. ;----------------------------------------------------------
  3. ; F_ADD -- version for use with assembly language programs
  4. ;
  5. ; Copyright Bob Kline 1988
  6. ;
  7. ; Purpose:
  8. ;       Add two single-precision floating-point numbers.
  9. ;
  10. ; Input:
  11. ;       DX:AX and CX:BX contain the two 4-byte reals
  12. ;       to be added in IEEE format.
  13. ;
  14. ; Output:
  15. ;       Result (IEEE) is single-precision real in DX:AX
  16. ;
  17. ; Other registers affected:
  18. ;       BX, CX, SI, DI, BP
  19. ;
  20. ; Other procedures called:
  21. ;       F_SUB
  22. ;
  23. ; Comments:
  24. ;       Sets external variable _errno to ERANGE if over-
  25. ;       flow occurs.  If a calling routine will be testing
  26. ;       _errno, it must first reset the variable to zero
  27. ;       to be sure that an error code is not left over
  28. ;       from some previous call.  If the signs of the two
  29. ;       operands differ the negative number is placed in
  30. ;       CX:BX, the sign removed, and F_SUB is called.
  31. ;----------------------------------------------------------
  32.  
  33.         .MODEL  SMALL
  34.  
  35.     PUBLIC    F_ADD
  36.         EXTRN   _errno:WORD,F_SUB:PROC
  37.  
  38. ERANGE    EQU    34
  39.  
  40.     .CODE
  41.  
  42. F_ADD    PROC
  43.  
  44. ; before doing anything else, see if one of the operands
  45. ;   is zero
  46.         MOV     SI,CX
  47.         OR      SI,BX
  48.         JZ      DONE
  49.         MOV     SI,DX
  50.         OR      SI,AX
  51.         JNZ     CHKSGN
  52.         MOV     AX,BX
  53.         MOV     DX,CX
  54.         RET
  55.  
  56. ; check the sign
  57. CHKSGN: MOV     SI,DX
  58.     XOR    SI,CX
  59.     JNS    SAME_SIGNS
  60.  
  61. ; signs are different -- put the one with the
  62. ;   minus sign in the subtrahend position,
  63. ;   remove its sign, and use F_SUB
  64.         OR      DX,DX
  65.         JNS     NOSWAP
  66.     XCHG    DX,CX
  67.     XCHG    AX,BX
  68. NOSWAP: AND    CX,7FFFh
  69.     CALL    F_SUB
  70. DONE:   RET
  71.  
  72. ; sign same for both -- save it
  73. SAME_SIGNS:
  74.     MOV    SI,DX
  75.     AND    SI,8000h
  76.     PUSH    SI
  77.  
  78. ; unpack exponent and remove bias
  79.     MOV    DI,DX
  80.     MOV    SI,CX
  81.     SHL    DX,1
  82.     SHL    CX,1
  83.     XCHG    DH,DL
  84.     XCHG    CH,CL
  85.     XOR    DH,DH
  86.     XOR    CH,CH
  87.     SUB    DX,127
  88.     SUB    CX,127
  89.     XCHG    DI,DX
  90.     XCHG    SI,CX
  91.  
  92. ; unpack the mantissas & slide over to the left
  93. ;   one position so we'll have elbowroom to catch
  94. ;   any lost low bit for rounding
  95.     AND    DX,7Fh
  96.     AND    CX,7Fh
  97.     OR    DX,80h
  98.     OR    CX,80h
  99.     SHL    AX,1
  100.     RCL    DX,1
  101.     SHL    BX,1
  102.     RCL    CX,1
  103.  
  104. ; use BP instead of CX for high word of 2nd operand so
  105. ;   we can use CX for shift counting
  106.     MOV    BP,CX
  107.  
  108. ; if exponents are equal, no adjustment necessary
  109.     CMP    DI,SI
  110.     JE    MATCHED
  111.  
  112. ; otherwise make first operand the larger of the two
  113.     JG    ADJUST
  114.     XCHG    DX,BP
  115.     XCHG    AX,BX
  116.     XCHG    DI,SI
  117.  
  118. ; make the exponents equal
  119. ADJUST: MOV    CX,DI
  120.     SUB    CX,SI
  121.  
  122. ; if the second number is so much smaller than than first
  123. ;   that adding it in will not make any difference, don't bother
  124.     CMP    CX,24
  125.     JA    SHIFTBACK
  126.  
  127. ; shift lower number to the right
  128. LOOP1:    SHR    BP,1
  129.     RCR    BX,1
  130.     LOOP    LOOP1
  131.  
  132. ; the exponents now match -- add the mantissas
  133. MATCHED:
  134.     ADD    AX,BX
  135.     ADC    DX,BP
  136.  
  137. ; see if we gained a position during addition --
  138. ;   shift right once if we did & increment exponent
  139.     TEST    DX,200h
  140.     JZ    SHIFTBACK
  141.     SHR    DX,1
  142.     RCR    AX,1
  143.     INC    DI
  144.  
  145. ; now we undo that left shift we did up above to make
  146. ;   room for a rounding bit -- and here's where we do
  147. ;   the rounding
  148. SHIFTBACK:
  149.     ADD    AX,1
  150.     ADC    DX,0
  151.     SHR    DX,1
  152.     RCR    AX,1
  153.  
  154. ; make the top bit of the mantissa invisible -- it's understood
  155.     AND    DX,7Fh
  156.  
  157. ; restore exponent bias
  158.     MOV    BX,DI
  159.     ADD    BX,127
  160.  
  161. ; test for valid exponent and re-pack
  162.     OR    BH,BH
  163.     JZ    EXP_OK
  164.         MOV     _errno,ERANGE
  165.     XOR    BH,BH
  166. EXP_OK: XCHG    BH,BL
  167.     SHR    BX,1
  168.     OR    DX,BX
  169.  
  170. ; get sign back and we're done
  171.     POP    CX
  172.     OR    DX,CX
  173.         RET
  174.  
  175. F_ADD    ENDP
  176.  
  177.     END
  178.